package com.email.box.config;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.function.Supplier;

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    private static final String CREATOR = "creator";

    private static final String MODIFIER = "modifier";

    private static final String ENTRY_TIME = "entryTime";

    private static final String UPDATE_TIME = "updateTime";

    private static final String STATUS = "status";

    public static final ThreadLocal<String> DEFAULT_USER = new ThreadLocal<>();

    @Override
    public void insertFill(MetaObject metaObject) {
        Object createTime = getDateValue(metaObject.getSetterType(ENTRY_TIME));

        fillValue(metaObject, CREATOR, () -> DEFAULT_USER.get());
        fillValue(metaObject, MODIFIER, () -> DEFAULT_USER.get());
        fillValue(metaObject, ENTRY_TIME, () -> createTime);
        fillValue(metaObject, UPDATE_TIME, () -> createTime);
        fillValue(metaObject, STATUS, () -> 1);
    }


    @Override
    public void updateFill(MetaObject metaObject) {
        Object updateTime = getDateValue(metaObject.getSetterType(UPDATE_TIME));
        fillValue(metaObject, MODIFIER, () -> DEFAULT_USER.get());
        fillValue(metaObject, UPDATE_TIME, () -> updateTime);
    }

    private void fillValue(MetaObject metaObject, String fieldName, Supplier<Object> valueSupplier) {
        if (!metaObject.hasGetter(fieldName)) {
            return;
        }
        if (metaObject.hasSetter(fieldName) && valueSupplier != null) {
            setFieldValByName(fieldName, valueSupplier.get(), metaObject);
        }
    }

    private Object getDateValue(Class<?> setterType) {
        if (Date.class.equals(setterType)) {
            return new Date();
        } else if (LocalDateTime.class.equals(setterType)) {
            return LocalDateTime.now();
        } else if (Long.class.equals(setterType)) {
            return System.currentTimeMillis();
        }
        return null;
    }
}
